/**
 * @file CommunicationService.h
 * @brief 通信服务类
 * @author Your Name
 * @date 2025-03-30
 */

#ifndef COMMUNICATIONSERVICE_H
#define COMMUNICATIONSERVICE_H

#include <QObject>
#include <QScopedPointer>
#include <QTimer>
#include <QDateTime>
#include <QMap>

#include "icommunicationstrategy.h"
#include "iprotocol.h"
#include "ProtocolDef.h"

/**
 * @brief 通信业务服务类
 * @details 负责协调通信策略和协议解析，完成业务逻辑处理
 */
class CommunicationService : public QObject {
    Q_OBJECT
public:
    explicit CommunicationService(QObject *parent = nullptr);
    ~CommunicationService();

    /**
     * @brief 初始化通信服务
     * @param commStrategy 通信策略对象
     * @param protocol 协议对象
     * @return 是否初始化成功
     */
    bool init(ICommunicationStrategy* commStrategy, IProtocol* protocol);

    /**
     * @brief 启动通信服务
     * @return 是否成功启动
     */
    bool start();

    /**
     * @brief 停止通信服务
     */
    void stop();

    /**
     * @brief 是否正在运行
     * @return 运行状态
     */
    bool isRunning() const;

    /**
     * @brief 发送设备控制命令
     * @param relayStatus 继电器状态位域
     * @return 是否发送成功
     */
    bool sendDeviceControl(uint8_t controlBits);

    /**
     * @brief 发送时间同步命令
     * @param timestamp 要同步的时间戳，默认使用当前时间
     * @return 是否发送成功
     */
    bool sendTimeSync(uint32_t timestamp = 0);

signals:
    /**
     * @brief 环境数据上报信号
     * @param temperature 温度值(0.1℃精度)
     * @param humidity 湿度值
     * @param battery 电量值
     */
    void environmentDataReceived(float temperature, uint8_t humidity, uint16_t battery);

    /**
     * @brief RFID考勤上报信号
     * @param cardId 卡号
     * @param timestamp 时间戳
     * @param statusCode 状态码
     */
    // void rfidReportReceived(uint32_t cardId, uint32_t timestamp, uint8_t statusCode);
    void rfidReportReceived(QString cardId, uint32_t timestamp, uint8_t statusCode);

    /**
     * @brief 心跳包接收信号
     * @param voltage 电压值(0.1V精度)
     * @param signalStrength 信号强度
     */
    void heartbeatReceived(float voltage, uint8_t signalStrength);

    /**
     * @brief 错误应答信号
     * @param errorCode 错误码
     */
    void errorResponseReceived(uint8_t errorCode);

    /**
     * @brief 通信状态变化信号
     * @param connected 是否已连接
     */
    void connectionStatusChanged(bool connected);

    /**
     * @brief 通信服务错误信号
     * @param code 错误码
     * @param message 错误信息
     */
    void serviceError(int code, const QString& message);

private slots:
    /**
     * @brief 处理接收到的数据
     * @param data 接收到的原始数据
     */
    void onDataReceived(const QByteArray& data);

    /**
     * @brief 处理解析后的数据包
     * @param cmdType 命令类型
     * @param data 数据内容
     */
    void onPacketParsed(uint8_t cmdType, const QByteArray& data);

    /**
     * @brief 处理协议错误
     * @param errCode 错误码
     * @param errMsg 错误信息
     */
    void onProtocolError(int errCode, const QString& errMsg);

    /**
     * @brief 处理通信错误
     * @param code 错误码
     * @param message 错误信息
     */
    void onCommunicationError(int code, const QString& message);

    /**
     * @brief 处理连接状态变化
     * @param connected 是否已连接
     */
    void onConnectionChanged(bool connected);

    /**
     * @brief 发送心跳包
     */
    void sendHeartbeat();

private:
    /**
     * @brief 解析环境数据
     * @param data 原始数据
     */
    void parseEnvironmentData(const QByteArray& data);

    /**
     * @brief 解析RFID报告
     * @param data 原始数据
     */
    void parseRfidReport(const QByteArray& data);

    /**
     * @brief 解析心跳包数据
     * @param data 原始数据
     */
    void parseHeartbeat(const QByteArray& data);

    /**
     * @brief 解析错误应答
     * @param data 原始数据
     */
    void parseErrorResponse(const QByteArray& data);

    /**
     * @brief 发送数据包
     * @param cmdType 命令类型
     * @param data 数据内容
     * @return 是否发送成功
     */
    bool sendPacket(uint8_t cmdType, const QByteArray& data);

    QScopedPointer<ICommunicationStrategy> m_commStrategy;  ///< 通信策略
    QScopedPointer<IProtocol> m_protocol;                  ///< 协议解析器
    QTimer m_heartbeatTimer;                               ///< 心跳定时器
    bool m_running;                                        ///< 运行状态
    QDateTime m_lastReceivedTime;                          ///< 最后一次接收数据的时间
};

#endif // COMMUNICATIONSERVICE_H
